using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;

namespace client
{
    public class ClientConfigurationManager
    {

        public static ApplicationManager getApplicationManager(){
            ApplicationManager am;

            Configuration c = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            ClientSection cs = c.GetSection("client") as ClientSection;

            if (cs != null)
            {
                am = new ApplicationManager(c,cs);
                return am;
            }

            Console.WriteLine("Cannot get client section in configuration file");
            return null;
        }
    }

    public class ApplicationElement : ConfigurationElement
    {
        private static ConfigurationProperty s_name;
        private static ConfigurationProperty s_idApplication;
        private static ConfigurationPropertyCollection s_properties;

        static ApplicationElement()
        {
            s_name = new ConfigurationProperty( 
                "name",
                typeof(string),
                null, 
                ConfigurationPropertyOptions.IsRequired);

            s_idApplication = new ConfigurationProperty(
                "id",
                typeof(ushort),
                null,
                ConfigurationPropertyOptions.IsRequired);

            s_properties = new ConfigurationPropertyCollection();

            s_properties.Add(s_name);
            s_properties.Add(s_idApplication);
        }

        [ConfigurationProperty("name", IsRequired = true)]
        public string Name
        {
            get { return (string)base[s_name]; }
            set { base[s_name] = value; }
        }

        [ConfigurationProperty("id" , IsRequired = true)]
        public ushort IdApplication
        {
            get { return (ushort)base[s_idApplication]; }
            set { base[s_idApplication] = value; }
        }
        
        protected override ConfigurationPropertyCollection Properties
        {
            get
            {
                return s_properties;
            }
        }
    }


    [ConfigurationCollection(typeof(ApplicationElement), AddItemName = "application",
      CollectionType = ConfigurationElementCollectionType.BasicMap)]
    public class ApplicationElementCollection : ConfigurationElementCollection
    {
        static ApplicationElementCollection()
        {
            m_properties = new ConfigurationPropertyCollection();
        }

        public ApplicationElementCollection()
        {
        }

        private static ConfigurationPropertyCollection m_properties;

        protected override ConfigurationPropertyCollection Properties
        {
            get { return m_properties; }
        }
        
        public override ConfigurationElementCollectionType CollectionType
        {
            get { return ConfigurationElementCollectionType.BasicMap; }
        }

        protected override string ElementName
        {
            get { return "application"; }
        }

        public ApplicationElement this[int index]
        {
            get { return (ApplicationElement)base.BaseGet(index); }
            set
            {
                if (base.BaseGet(index) != null)
                {
                    base.BaseRemoveAt(index);
                }
                base.BaseAdd(index, value);
            }
        }

        protected override void BaseAdd(ConfigurationElement element)
        {
            BaseAdd(element, false);
        }

        public void Add(ApplicationElement thing)
        {
            BaseAdd(thing);
        }

        public void Remove(string name)
        {
            base.BaseRemove(name);
        }

        public void Remove(ApplicationElement thing)
        {
            base.BaseRemove(GetElementKey(thing));
        }

        public void Clear()
        {
            base.BaseClear();
        }

        public void RemoveAt(int index)
        {
            base.BaseRemoveAt(index);
        }

        public string GetKey(int index)
        {
            return (string)base.BaseGetKey(index);
        }

        protected override ConfigurationElement CreateNewElement()
        {
            return new ApplicationElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return (element as ApplicationElement).Name;
        }
    }

    public class ClientSection: ConfigurationSection
    {
        private static ConfigurationProperty s_id;
        private static ConfigurationProperty s_groupid;
        private static ConfigurationProperty s_path;
        private static ConfigurationProperty s_logPath;
        private static ConfigurationProperty s_applications;

        private static ConfigurationPropertyCollection s_properties;

        static ClientSection()
        {
            // Predefine properties here
            s_id = new ConfigurationProperty(
                "id",
                typeof(uint),
                null,
                ConfigurationPropertyOptions.IsRequired
            );

            s_groupid = new ConfigurationProperty(
                "groupid",
                typeof(ushort),
                null,
                ConfigurationPropertyOptions.IsRequired
            );

            s_path = new ConfigurationProperty(
                "path",
                typeof(string),
                null,
                ConfigurationPropertyOptions.IsRequired
            );

            s_logPath = new ConfigurationProperty(
                "logPath",
                typeof(string),
                null,
                ConfigurationPropertyOptions.IsRequired
            );

            s_applications = new ConfigurationProperty(
                "applications",
                typeof(ApplicationElementCollection),
                null,
                ConfigurationPropertyOptions.None
            );

            s_properties = new ConfigurationPropertyCollection();
            
            s_properties.Add(s_id);
            s_properties.Add(s_groupid);
            s_properties.Add(s_path);
            s_properties.Add(s_logPath);
            s_properties.Add(s_applications);
        }
         
        [ConfigurationProperty("id", IsRequired=true)]
        public uint Id
        {
            get { return (uint)base[s_id]; }
            set { base[s_id] = value; }
        }

        [ConfigurationProperty("groupid", IsRequired = true)]
        public ushort GroupId
        {
            get { return (ushort)base[s_groupid]; }
            set { base[s_groupid] = value; }
        }


        [ConfigurationProperty("path", IsRequired=true)]
        public string Path
        {
            get { return (string)base[s_path]; }
            set { base[s_path] = value; }
        }

        [ConfigurationProperty("logPath", IsRequired=true)]
        public string LogPath
        {
            get { return (string)base[s_logPath]; }
            set { base[s_logPath] = value; }
        }

        [ConfigurationProperty("application")]
        public ApplicationElementCollection Applications
        {
            get { return (ApplicationElementCollection)base[s_applications]; }
            set { base[s_applications] = value; }
        }

        protected override ConfigurationPropertyCollection Properties
        {
            get { return s_properties; }
        }
    }
}
